/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.thienloc.omap.controller;

import com.thienloc.omap.entity.RequestQueue;
import com.thienloc.omap.entity.ServiceSuggestion;
import com.thienloc.omap.jdbc.dao.TblSmsBroadcastingDao;
import com.thienloc.omap.jdbc.entity.TblSmsBroadcasting;
import com.thienloc.omap.service.broadcast.BroadcastService;
import com.thienloc.omap.session.RequestQueueFacade;
import com.thienloc.omap.session.ServiceSuggestionFacade;
import com.thienloc.omap.util.JsfUtil;
import java.io.IOException;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 * @author GiangLT
 */
@ManagedBean
@ViewScoped
public class RequestQueueSuggestBean extends BaseBean implements Serializable {

    @EJB
    private RequestQueueFacade requestQueueFacade;
    @EJB
    private ServiceSuggestionFacade serviceSuggestionFacade;
    private List<RequestQueue> list;
    private final int MAX_RESULT = 250;
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    private final String STATUS_NEED_TO_HELP = "NEED_TO_HELP";
    private final String STATUS_SENDING_HELP = "SENDING_HELP";
    private final String STATUS_COMPLETED = "COMPLETED";
    private Map<String, String> helpContentMap;
    private String actionCommitter;
    private RequestQueue toBeCompletedRequest;

    @PostConstruct
    void init() {
        try {
            List<String> statusesToSearch = new ArrayList<String>();
            statusesToSearch.add(STATUS_NEED_TO_HELP);

            list = requestQueueFacade.findByStatus(statusesToSearch, MAX_RESULT, true);

            for (RequestQueue requestQueue : list) {
                requestQueue.setSelectTime(new Date());
            }

            List<ServiceSuggestion> suggestions = serviceSuggestionFacade.findAll();
            helpContentMap = new TreeMap<String, String>();
            for (ServiceSuggestion serviceSuggestion : suggestions) {
                helpContentMap.put(serviceSuggestion.getShortHelpContent(), serviceSuggestion.getId().toString());
            }
            toBeCompletedRequest = new RequestQueue();
        } catch (Exception ex) {
            logAndNotifyError("Error", ex);
        }
    }

    private void updateRequestStatus(RequestQueue request, String status) throws Exception {
        request.setStatus(status);
        request.setLastCheckTime(new Date());
        requestQueueFacade.edit(request);
    }

    public void prepareSetComplete(Long id) {
        try {
            toBeCompletedRequest = requestQueueFacade.find(id);
        } catch (Exception ex) {
            logAndNotifyError("Lỗi!", ex);
        }
    }

    public void setCompleted(Long id) {
        try {
            toBeCompletedRequest.setStatus("COMPLETED");
            toBeCompletedRequest.setLastCheckTime(new Date());
            requestQueueFacade.edit(toBeCompletedRequest);
            logger.warn("[{}]: {} set COMPLETED status for request {}", new Object[]{getUsername(), this.actionCommitter, toBeCompletedRequest});
            JsfUtil.addSuccessMessage("Thành công", "Đã chuyển yêu cầu của số " + toBeCompletedRequest.getMsisdn() + " sang trạng thái COMPLETED");
            init();
        } catch (Exception ex) {
            logAndNotifyError("Error", ex);
        }
    }

    public void updateAll() {
        if (!list.isEmpty()) {
            int cnt = 0;
            TblSmsBroadcastingDao tblSmsBroadcastingDao;
            try {
                tblSmsBroadcastingDao = new TblSmsBroadcastingDao();
            } catch (Exception ex) {
                logAndNotifyError("Cannot connect to TBL_SMS_BROADCASTING", ex);
                return;
            }

            BroadcastService broadcastService = null;
            try {
                broadcastService = new BroadcastService();
                broadcastService.connect();
            } catch (Exception ex) {
                logAndNotifyError("Cannot connect to BroadcastService", ex);
                return;
            }

            for (RequestQueue currentRequest : list) {
                try {
                    RequestQueue oldRequest = requestQueueFacade.find(currentRequest.getRequestId());

                    if ((oldRequest.getStatus() != null && !oldRequest.getStatus().equals(STATUS_SENDING_HELP))
                            && currentRequest.getServiceSuggestionId() != null) {
                        updateRequestStatus(currentRequest, STATUS_SENDING_HELP);//thuc hien update vao Db
                        logger.trace("[{}] {}: Updated to SENDING_HELP: \"{}\"", new Object[]{getUsername(), currentRequest.getMsisdn(), currentRequest.getRequestDetail()});

                        String helpContent;
                        try {
                            helpContent = serviceSuggestionFacade.find(currentRequest.getServiceSuggestionId()).getHelpContent();
                        } catch (Exception ex) {
                            updateRequestStatus(currentRequest, STATUS_NEED_TO_HELP);
                            logAndNotifyError("Cannot sent message to BroadcastService", ex);
                            continue;
                        }

                        try {
                            StringBuilder sb = new StringBuilder();
                            int seq = sessionBean.getBroadcastInstantSeq();
                            sb.append(seq);//????
                            sb.append(";");
                            sb.append(currentRequest.getMsisdn());
                            sb.append(";");
                            sb.append(currentRequest.getCpNumber());
                            sb.append(";");
                            sb.append(helpContent);
                            sb.append(";");
                            sb.append(currentRequest.getDeliverProvider());
                            sb.append("|");
                            broadcastService.send(sb.toString());
                            logger.debug("[{}] Sent to BroadcastService: {}", getUsername(), sb.toString());
                        } catch (IOException ex) {
                            updateRequestStatus(currentRequest, STATUS_NEED_TO_HELP);
                            logAndNotifyError("Cannot sent message to BroadcastService", ex);
                            continue;
                        }

                        //TO DO: có nên update phía web ko?
                        try {
                            TblSmsBroadcasting tblSmsBroadcasting = new TblSmsBroadcasting();
                            tblSmsBroadcasting.setSc(currentRequest.getCpNumber());
                            tblSmsBroadcasting.setMsisdn(currentRequest.getMsisdn());
                            tblSmsBroadcasting.setProvider(currentRequest.getDeliverProvider());
                            tblSmsBroadcasting.setResult("OK");
                            tblSmsBroadcasting.setSms(helpContent);
                            tblSmsBroadcasting.setSentTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
                            tblSmsBroadcastingDao.add(tblSmsBroadcasting);
                            logger.trace("[{}] {}: Inserted into to TBL_SMS_BROADCASTING", getUsername(), currentRequest.getMsisdn());
                        } catch (Exception ex) {
                            logAndNotifyError("Cannot update to TBL_SMS_BROADCASTING", ex);
                        }

                        updateRequestStatus(currentRequest, STATUS_COMPLETED);
                        logger.trace("[{}] {}: Updated to COMPLETED", getUsername(), currentRequest.getMsisdn());

                        cnt++;
                    } else {
                        logger.info("[{}] {}: Request status SENDING_HELP", getUsername(), currentRequest.getMsisdn());
                    }
                } catch (Exception ex) {
                    String error = "Lỗi! ";
                    logger.error("[{}]: ", getUsername(), ex);
                    JsfUtil.addErrorMessage(error, ex.getMessage());
                }
            }
            if (cnt > 0) {
                JsfUtil.addSuccessMessage("Thành công!", "Đã gửi tin nhắn tới " + cnt + " số ");
            }
        }

        init();
    }

    public Map<String, String> getHelpContentMap() {
        return helpContentMap;
    }

    public List<RequestQueue> getList() {
        return list;
    }

    private void logAndNotifyError(String error, Exception ex) {
        logger.error("[{}]: {}", new Object[]{getUsername(), error, ex});
        JsfUtil.addErrorMessage("Lỗi! ", error);
    }

    public RequestQueue getToBeCompletedRequest() {
        return toBeCompletedRequest;
    }

    public String getActionCommitter() {
        return actionCommitter;
    }

    public void setActionCommitter(String actionCommitter) {
        this.actionCommitter = actionCommitter;
    }
}
